package com.example.cash.craft.service.impl;

import com.example.cash.craft.dao.cache.IProductCacheRepository;
import com.example.cash.craft.dao.persist.repository.ICategoryRepository;
import com.example.cash.craft.dao.persist.repository.IProductRepository;
import com.example.cash.craft.exception.ServiceException;
import com.example.cash.craft.pojo.entity.Product;
import com.example.cash.craft.pojo.param.ProductAddNewParam;
import com.example.cash.craft.pojo.param.ProductUpdateParam;
import com.example.cash.craft.pojo.vo.CategoryVO;
import com.example.cash.craft.pojo.vo.PageData;
import com.example.cash.craft.pojo.vo.ProductVO;
import com.example.cash.craft.service.IProductService;
import com.example.cash.craft.web.StateCode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ProductServiceImpl implements IProductService {

    @Value("${cash-craft.config.default-page-size}")
    private Integer defaultPageSize;
    @Autowired
    private IProductRepository productRepository;
    @Autowired
    private ICategoryRepository categoryRepository;
    @Autowired
    private IProductCacheRepository productCacheRepository;

    @Override
    public void addNew(ProductAddNewParam param) {
        Long categoryId = param.getCategoryId();
        CategoryVO category = categoryRepository.selectById(categoryId);
        if (category == null) {
            throw new ServiceException(StateCode.ERROR_NOT_FOUND, "类别不存在");
        }

        Product product = new Product();
        BeanUtils.copyProperties(param, product);
        product.setCategoryName(category.getName());
        product.setSales(0);
        productRepository.insert(product);
    }

    @Override
    public void deleteById(Long id) {
        ProductVO findResult = productRepository.selectById(id);
        if (findResult == null) {
            throw new ServiceException(StateCode.ERROR_NOT_FOUND, "商品不存在");
        }
        productRepository.deleteById(id);
    }

    @Override
    public void updateById(Long id, ProductUpdateParam param) {
        ProductVO findResult = productRepository.selectById(id);
        if (findResult == null) {
            throw new ServiceException(StateCode.ERROR_NOT_FOUND, "商品不存在");
        }

        Long categoryId = param.getCategoryId();
        CategoryVO category = categoryRepository.selectById(categoryId);
        if (category == null) {
            throw new ServiceException(StateCode.ERROR_NOT_FOUND, "类别不存在");
        }

        Product product = new Product();
        BeanUtils.copyProperties(param, product);
        product.setId(id);
        product.setCategoryName(category.getName());
        productRepository.updateById(product);
    }

    @Override
    public ProductVO selectById(Long id) {
        ProductVO findResult = productCacheRepository.selectById(id);
        if (findResult == null) {
            throw new ServiceException(StateCode.ERROR_NOT_FOUND, "商品不存在");
        }
        return findResult;
    }

    @Override
    public PageData<ProductVO> listAll(Integer page) {
        return productCacheRepository.listAll(page, defaultPageSize);
    }

    @Override
    public PageData<ProductVO> listByCategoryId(Long categoryId, Integer page) {
        return productCacheRepository.listByCategoryId(categoryId, page, defaultPageSize);
    }

    @Override
    public void rebuildCache() {
        productCacheRepository.deleteList();
        productCacheRepository.deleteAllItems();
        productCacheRepository.deleteKeysSet();

        Integer page = 1;
        Integer pageSize = defaultPageSize;
        Integer maxPage;
        do {
            PageData<ProductVO> pageData = productRepository.listAll(page, pageSize);
            maxPage = pageData.getMaxPage();
            List<ProductVO> list = pageData.getList();
            productCacheRepository.saveAll(list);
            for (ProductVO item : list) {
                productCacheRepository.save(item);
            }
            page++;
        } while (page <= maxPage);

        List<CategoryVO> categoryList = categoryRepository.listAll(1, Integer.MAX_VALUE).getList();
        for (CategoryVO item : categoryList) {
            Long categoryId = item.getId();
            productCacheRepository.deleteListByCategoryId(categoryId);
            PageData<ProductVO> productList = productRepository.listByCategoryId(categoryId, 1, Integer.MAX_VALUE);
            productCacheRepository.saveByCategoryId(categoryId, productList.getList());
        }
    }

}
